<?php
/*
Plugin Name: Vue - SPA 
Plugin URI: https://www.npc.ink/277241.html
Description: 将vue构建的页面嵌入WordPress 中并产生交互
Author: Muze
Author URI: https://www.npc.ink
Version: 1.0.0
*/





// 允许WordPress Rest API 跨域访问：
function add_custom_headers() {
    add_filter( 'rest_pre_serve_request', function( $value ) {
        header( 'Access-Control-Allow-Headers: Authorization, X-WP-Nonce,Content-Type, X-Requested-With');
        header( 'Access-Control-Allow-Origin: *');
        header( 'Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE');
        header( 'Access-Control-Allow-Credentials: true');
        return $value;
    });
}
add_action( 'rest_api_init', 'add_custom_headers', 15 );


/*****************创建新的文章类型 */
//注册自定义文章类型-menu
/**
 * Register a custom post type called "menu".
 *
 * @see get_post_type_labels() for label keys.
 */
add_action('init', 'my_custom_post_menu');

function my_custom_post_menu()
{
	$labels = array(
		'name' => _x('采集网站', 'post type 名称'),
		'singular_name' => _x('采集网站', 'post type 单个 item 时的名称，因为英文有复数'),
		'add_new' => _x('新建采集网站', '添加新内容的链接名称'),
		'add_new_item' => __('新建采集网站'),
		'edit_item' => __('编辑采集网站'),
		'new_item' => __('新采集网站'),
		'all_items' => __('所有采集网站'),
		'view_item' => __('查看采集网站'),
		'search_items' => __('搜索采集网站'),
		'not_found' => __('没有找到有关采集网站'),
		'not_found_in_trash' => __('回收站里面没有相关采集网站'),
		'parent_item_colon' => '',
		'menu_name' => '采集网站'
	);
	$args = array(
		'labels' => $labels,
		'description' => '我们网站的采集网站信息',
		'public' => true,
		'menu_position' => 5,
		'supports' => array('title'),
		'has_archive' => true
	);
	register_post_type('menu', $args);
}
add_action('init', 'my_taxonomies_menu', 0);



/*****************创建新的采集发布栏目类型 */
//注册自定义文章类型-menu_type
/**
 * Register a custom post type called "menu_type".
 *
 * @see get_post_type_labels() for label keys.
 */
add_action('init', 'my_custom_post_menu_types');
function my_custom_post_menu_types()
{
	$labels = array(
		'name' => _x('采集发布栏目', 'post type 名称'),
		'singular_name' => _x('采集发布栏目', 'post type 单个 item 时的名称，因为英文有复数'),
		'add_new' => _x('新建采集发布栏目', '添加新内容的链接名称'),
		'add_new_item' => __('新建采集发布栏目'),
		'edit_item' => __('编辑采集发布栏目'),
		'new_item' => __('新采集发布栏目'),
		'all_items' => __('所有采集发布栏目'),
		'view_item' => __('查看采集发布栏目'),
		'search_items' => __('搜索采集发布栏目'),
		'not_found' => __('没有找到有关采集发布栏目'),
		'not_found_in_trash' => __('回收站里面没有相关采集发布栏目'),
		'parent_item_colon' => '',
		'menu_name' => '采集发布栏目'
	);
	$args = array(
		'labels' => $labels,
		'description' => '我们网站的发布栏目网站信息',
		'public' => true,
		'menu_position' => 5,
		'supports' => array('title'),
		'has_archive' => true
	);
	register_post_type('menu_type', $args);
}

//创建元数据
$new_meta_boxes_types = array(
    'gl_menu' => array(
        'name' => '_gl_menu',
        'std'  => '关联采集网站',
        'utd'  => '关联采集网站'
    )
);





//添加元数据
//函数new_meta_boxes_type()：用于创建新的元框类型
function new_meta_boxes_type(){
    //声明全局变量
    global $post,$new_meta_boxes_types;
    //遍历new_meta_boxes_types数组
    foreach($new_meta_boxes_types as $mate_box){
        //获取url的值
        $meta_box_value1 = get_post_meta($post->ID,$mate_box['name'],true);
        //显示URL
        if($meta_box['std'] == '_gl_menu'){
            echo '<h3>'.$mate_box['std'].'</h3>';
            //定义数组，用于获取post_type为menu的post
            $types = array(
                'post_type' => 'menu',
            );
            //获取post_type为menu的post
            $type_list = get_posts($types);
            ?>
               <select name="<?php echo $mate_box['name'];?>" value="<?php echo $meta_box_value1;?>">
                   <option value="">请选择</option>
                   <?php foreach($type_list as $type_list_key => $type_list_value){?>
                        <option value="<?php echo $type_list_value->ID;?>" <?php if($meta_box_value1 == $type_list_value->ID){echo 'selected';}?>><?php echo $type_list_value->post_title;?></option>
                   <?php }?>
               </select>
            <?php
        }
    }
}


/**
 * 创建自定义字段模块
 */
function create_meta_box1()
{
	if (function_exists('add_meta_box')) {
		add_meta_box('new_meta_boxes_type', '自定义模块', 'new_meta_boxes_type', 'menu-type', 'normal', 'high');
	}
}

//将函数连接到指定action（动作）
add_action('admin_menu', 'create_meta_box1');
add_action('save_post', 'save_postdata1');


//保存文章数据
function save_postdata1($post_id)
{
	global $new_meta_boxes_types;
	// 判断当前用户是否可以编辑文章
	if (!current_user_can('edit_posts', $post_id))
		return;
	// 遍历新元数据框类型
	foreach ($new_meta_boxes_types as $meta_box) {
		// 获取当前元数据框的值
		$data = $_POST[$meta_box['name']];
		// 如果当前元数据框的值为空，则删除该元数据框的值
		if ($data == "")
			delete_post_meta($post_id, $meta_box['name'], get_post_meta($post_id, $meta_box['name'], true));
		// 否则更新该元数据框的值
		else
			update_post_meta($post_id, $meta_box['name'], $data);
	}
}


add_filter('manage_menu_type_posts_columns', 'add_new_menu_type_columns');
function add_new_menu_type_columns($book_columns)
{
	$new_columns['cb'] = '<input type="checkbox" />'; //这个是前面那个选框，不要丢了   
	$new_columns['id'] = __('ID');
	$new_columns['title'] = '栏目';
	$new_columns['_gl_menu'] = '关联菜单';
	//直接返回一个新的数组   
	return $new_columns;
}


add_action('manage_posts_custom_column', 'manage_menu_type_columns', 10, 2);
// 添加一个名为manage_menu_type_columns的函数，该函数接受两个参数：$column_name和$id
function manage_menu_type_columns($column_name, $id)
{
	// 声明全局变量$wpdb
	global $wpdb;
	// 根据$column_name的值，执行不同的操作
	switch ($column_name) {
		// 如果$column_name的值为id，则输出$id
		case 'id':
			echo $id;
			break;
		// 如果$column_name的值为_gl_menu，则输出get_the_title函数的返回值，该函数的参数为get_post_meta函数的返回值，该函数的参数为$id和_gl_menu
		case '_gl_menu':  
			$urls = get_the_title(get_post_meta($id,'_gl_menu',true));
			echo $urls;
			break;
		// 如果$column_name的值不是id和_gl_menu，则不执行任何操作
		default:
			break;
	}
}






/*****************创建新的采集计时任务类型 */
//注册自定义文章类型-renwu_type
/**
 * Register a custom post type called "renwu_type".
 *
 * @see get_post_type_labels() for label keys.
 */
add_action('init', 'my_custom_post_renwu_type');

function my_custom_post_renwu_type()
{
	$labels = array(
		'name' => _x('计划任务', 'post type 名称'),
		'singular_name' => _x('计划任务栏目', 'post type 单个 item 时的名称，因为英文有复数'),
		'add_new' => _x('新建计划任务栏目', '添加新内容的链接名称'),
		'add_new_item' => __('新建计划任务栏目'),
		'edit_item' => __('编辑计划任务栏目'),
		'new_item' => __('新计划任务栏目'),
		'all_items' => __('所有计划任务栏目'),
		'view_item' => __('查看计划任务栏目'),
		'search_items' => __('搜索计划任务栏目'),
		'not_found' => __('没有找到有关计划任务栏目'),
		'not_found_in_trash' => __('回收站里面没有相关计划任务栏目'),
		'parent_item_colon' => '',
		'menu_name' => '计划任务'
	);
	$args = array(
		'labels' => $labels,
		'description' => '我们网站的计划任务网站信息',
		'public' => true,
		'menu_position' => 5,
		'supports' => array('title'),
		'has_archive' => true
	);
	register_post_type('renwu_type', $args);
}





//创建元数据
$new_meta_boxes_types1 = array(
    'jishi_menu' => array(
        'name' => '_jishi_menu',
        'std'  => '关联平台和规则',
        'utd'  => '关联平台和规则'
    ),
    'is_strat' => array(
        'name' => '_is_strat',
        'std'  => '开启/关闭计划任务',
        'utd'  => '开启/关闭计划任务'
    ),
    'is_lanmu' => array(
        'name' => '_is_lanmu',
        'std'  => '关联栏目',
        'utd'  => '关联栏目'
    ),
    'is_times' => array(
        'name' => '_is_times',
        'std'  => '计划时间',
        'utd'  => '计划时间'
    )
);





//添加元数据
function new_meta_boxes_types1(){
    global $post,$new_meta_boxes_types1;
    foreach($new_meta_boxes_types1 as $mate_box){
        //获取url的值
        $meta_box_value1 = get_post_meta($post->ID,$mate_box['name'],true);
        //显示URL
        if($mate_box['name'] == '_jishi_menu'){
            $cateList = get_posts(array(
                'post_type' => 'menu',
                'hide_empty' => false
            ));
            echo '<h3>'.$mate_box['std'].'</h3>';
            
            foreach($cateList as $vv){
				if(!empty($meta_box_value1) && in_array($vv->ID,$meta_box_value1)){
					$vv->checkeds = 'checked';
				}else{
					$vv->checkeds = ''; 
				}
			}
            foreach($cateList as $vv){
				echo  '<div style="display: inline-flex; flex-direction: row; justify-content: flex-start; align-items:center;" id="userlistId">';
				echo  '<label><input type="checkbox" value="'.$vv->ID.'" '.$vv->checkeds.'  name="'.$mate_box['name'].'[]" />'.$vv->post_title.'</label>';
				echo  '</div>';
			}
        }
        if($mate_box['name'] == '_is_strat'){
            echo '<h3>'.$mate_box['std'].'</h3>';
            ?>
                <div style="display:flex;">
                    <!-- Rounded switch -->
                    <label class="switch">
                        <input type="radio" name="<?php echo $mate_box['name'];?>" <?php if($meta_box_value1 == 1){ echo 'checked = checked';} ?> value="1">
                        <span class="slider round">开启</span>
                        <input type="radio" name="<?php echo $mate_box['name'];?>" <?php if($meta_box_value1 == 2){ echo 'checked = checked';} ?> value="2">
                        <span class="slider round">关闭</span>
                    </label>
                </div>
            <?php
        }
        
        if($mate_box['name'] == '_is_lanmu'){
            echo '<h3>'.$mate_box['std'].'</h3>';
            $terms = get_terms(array(
                'taxonomy' => 'category',
                'hide_empty' => false
            ));
            foreach($terms as $vv){
				if(!empty($meta_box_value1) && in_array($vv->term_id,$meta_box_value1)){
					$vv->checkeds = 'checked';
				}else{
					$vv->checkeds = ''; 
				}
			}
            foreach($terms as $vv){
				echo  '<div style="display: inline-flex; flex-direction: row; justify-content: flex-start; align-items:center;" id="userlistId">';
				echo  '<label><input type="checkbox" value="'.$vv->term_id.'" '.$vv->checkeds.'  name="'.$mate_box['name'].'[]" />'.$vv->name.'</label>';
				echo  '</div>';
			}
        }
        if($mate_box['name'] == '_is_times'){
            echo '<h3>'.$mate_box['std'].'</h3>';
            ?>
                <div style="display:flex;">
                    <!-- Rounded switch -->
                    <label class="switch">
                        <input type="radio" name="<?php echo $mate_box['name'];?>" <?php if($meta_box_value1 == '9:00'){ echo 'checked = checked';} ?> value="9:00">
                        <span class="slider round">每天9:00</span>
                        <input type="radio" name="<?php echo $mate_box['name'];?>" <?php if($meta_box_value1 == '12:00'){ echo 'checked = checked';} ?> value="12:00">
                        <span class="slider round">每天12:00</span>
                    </label>
                </div>
            <?php
        }
    }
}

/**
 * 创建自定义字段模块
 */
function create_meta_box2()
{
	if (function_exists('add_meta_box')) {
		add_meta_box('new_meta_boxes_types1', '自定义模块', 'new_meta_boxes_types1', 'renwu_type', 'normal', 'high');
	}
}

//将函数连接到指定action（动作）
add_action('admin_menu', 'create_meta_box2');
add_action('save_post', 'save_postdata2');

//保存文章数据
function save_postdata2($post_id)
{
	global $new_meta_boxes_types1;
    $post_types = get_post_type();
    if($post_types == 'renwu_type'){
        // //关掉浏览器 PHP脚本也可以继续执行
        // ignore_user_abort();
        // set_time_limit(0);//通过set_time_limit(0)可以让程序无限制的执行下去
        // $interval = 60*1;// 每隔一分钟运行
        // do{
        //     $run = include 'cons.php';
        //     if(!$run){
        //         die('process abort');
        //     }
        //     print_r('213');
        //     sleep($interval);
        //}
    }
	if (!current_user_can('edit_posts', $post_id))
		return;
	foreach ($new_meta_boxes_types1 as $meta_box) {
		$data = $_POST[$meta_box['name']];
		if ($data == "")
			delete_post_meta($post_id, $meta_box['name'], get_post_meta($post_id, $meta_box['name'], true));
		else
			update_post_meta($post_id, $meta_box['name'], $data);
	}
}


add_filter('manage_renwu_type_posts_columns', 'add_new_renwu_type_columns');
function add_new_renwu_type_columns($book_columns)
{
	$new_columns['cb'] = '<input type="checkbox" />'; //这个是前面那个选框，不要丢了   
	$new_columns['id'] = __('ID');
	$new_columns['title'] = '计划任务名称';
	$new_columns['_is_strat'] = '是否开启';
	//直接返回一个新的数组   
	return $new_columns;
}

add_action('manage_posts_custom_column', 'manage_renwu_type_columns', 10, 2);
function manage_renwu_type_columns($column_name, $id)
{
	global $wpdb;
	switch ($column_name) {
		case 'id':
			echo $id;
			break;
        case 'title' :
            //关联的平台文章
            $meta_box_value1 = get_post_meta($id,'_jishi_menu',true);
            $the_query = get_post($meta_box_value1);
            echo $the_query->post_title;
            break;
        case '_is_strat' :
            //关联的平台文章
            $meta_box_value1 = get_post_meta($id,'_is_strat',true);
            if($meta_box_value1 == 1){
                echo '<span style="color:red;">是</span>';
            }else{
                echo '否';
            }
            break;
		default:
			break;
	}
}







































//创建元数据
$new_meta_boxes = array(
    'menu' => array(
        'name' => '_menu',
        'std'  => '网站URL',
        'utd'  => '网站URL'
    ),
    'title' => array(
        'name' => '_title',
        'std'  => '网站标题',
        'utd'  => '网站标题'
    ),
    'time' => array(
        'name' => '_time',
        'std'  => '网站详情页发布时间',
        'utd'  => '网站详情页发布时间'
    ),
    'description' => array(
        'name' => '_description',
        'std'  => '网站详情页描述',
        'utd'  => '网站详情页描述'
    ),
    'content' => array(
        'name' => '_content',
        'std'  => '网站详情页内容',
        'utd'  => '网站详情页内容'
    ),
    'Infotitle' => array(
        'name' => '_Infotitle',
        'std'  => '网站详情页标题',
        'utd'  => '网站详情页标题'
    )
);
//添加元数据
function new_meta_boxes(){
    global $post,$new_meta_boxes;
    foreach($new_meta_boxes as $mate_box){
        //获取url的值
        $meta_box_value = get_post_meta($post->ID,$mate_box['name'],true);
        //显示URL
        echo '<h3>'.$mate_box['std'].'</h3>';
        echo '<input name="'.$mate_box['name'].'" value="'.$meta_box_value.'" style="width:100%;"></input>';
    }
}


/**
 * 创建自定义字段模块
 */
function create_meta_box()
{
	if (function_exists('add_meta_box')) {
		add_meta_box('new_meta_boxes', '自定义模块', 'new_meta_boxes', 'menu', 'normal', 'high');
	}
}

//将函数连接到指定action（动作）
add_action('admin_menu', 'create_meta_box');
add_action('save_post', 'save_postdata');


//保存文章数据
function save_postdata($post_id)
{
	global $new_meta_boxes;
	if (!current_user_can('edit_posts', $post_id))
		return;
	foreach ($new_meta_boxes as $meta_box) {
		$data = $_POST[$meta_box['name']];
		if ($data == "")
			delete_post_meta($post_id, $meta_box['name'], get_post_meta($post_id, $meta_box['name'], true));
		else
			update_post_meta($post_id, $meta_box['name'], $data);
	}
}

add_filter('manage_menu_posts_columns', 'add_new_menu_columns');
function add_new_menu_columns($book_columns)
{
	$new_columns['cb'] = '<input type="checkbox" />'; //这个是前面那个选框，不要丢了   
	$new_columns['id'] = __('ID');
	$new_columns['title'] = '标题';
	$new_columns['_menu'] = 'URL';
	//直接返回一个新的数组   
	return $new_columns;
}
add_action('manage_posts_custom_column', 'manage_menu_columns', 10, 2);
function manage_menu_columns($column_name, $id)
{
	global $wpdb;
	switch ($column_name) {
		case 'id':
			echo $id;
			break;

		case '_menu':  
			$urls = get_post_meta($id,'_menu',true);
			echo $urls;
			break;
		default:
			break;
	}
}





//接口
require_once plugin_dir_path(__FILE__) . 'interface.php';

//创建一个菜单
function vuespa_create_menu_page()
{
    add_menu_page(
        'VueSpa选项',                   // 此菜单对应页面上显示的标题
        'VueSpa',                      // 要为此实际菜单项显示的文本
        'administrator',               // 哪种类型的用户可以看到此菜单
        'vuespa_id',                   //  此菜单项的唯一ID（即段塞）
        'vuespa_menu_page_display',    // 呈现此页面的菜单时要调用的函数的名称 'vuespa_menu_page_display'
        'dashicons-admin-customizer',  //图标 - 默认图标
        '500.1',                       //位置
    );
} // end vuespa_create_menu_page 
add_action('admin_menu', 'vuespa_create_menu_page');

//菜单回调 - 展示的内容
function vuespa_menu_page_display()
{
    
?>

    <!--在默认WordPress“包装”容器中创建标题-->
    <div class="wrap">
        <!--标题-->
        <h2><?php echo esc_html(get_admin_page_title()); ?></h2>
        <!--提供Vue挂载点-->
        <div id="vuespa">此内容将在挂载Vue后被替换{{data}}</div>
    </div>



<?php

    //展示准备的数据
    echo "<pre>";
    print_r(vuespa_data());
    echo "</pre>";

    echo "<h3>调用选项值</h3>";
    echo get_option('dataOne');
    echo "<br/>";
    echo get_option('dataTwo');
    echo "<br/>";
    print_r(get_option('dataName'));
    echo "<br/>";
    echo get_option('dataImage');
    echo "<br/>";
    echo get_option('dataSelectedImage');
} // vuespa_menu_page_display



//载入所需 JS 和 CSS 资源 并传递数据
function vuespa_load_vues($hook)
{
    //判断当前页面是否是指定页面，是则继续加载
    if ('toplevel_page_vuespa_id' != $hook) {
        return;
    }
    //版本号
    $ver = '53';
    //加载到页面顶部
    wp_enqueue_style('vites', plugin_dir_url(__FILE__) . 'vites/dist/index.css', array(), $ver, false);
    //加载到页面底部
    wp_enqueue_script('viteJS', plugin_dir_url(__FILE__) . 'vites/dist/index.js', array(), $ver, true);

    $pf_api_translation_array = array(
        'route' => esc_url_raw(rest_url()),    //路由
        'nonce' => wp_create_nonce('wp_rest'), //验证标记
        'data' => vuespa_data(),               //自定义数据
    );
    wp_localize_script('viteJS', 'dataLocal', $pf_api_translation_array); //传给vite项目
}
//样式加载到后台
add_action('admin_enqueue_scripts', 'vuespa_load_vues');


//准备待传输的数据
function vuespa_data()
{
    $person = [
        "str" => "Hello, world! - Npcink",
        "num" => 25,
        "city" => [1, 2, 3, 4, 5],
        "user" => vuespa_get_user_meat(),
    ];
    return $person;
}


//整理并提供用户信息
function vuespa_get_user_meat()
{
    //获取所有角色
    $editable_roles = wp_roles()->roles;
    $roles = array_keys($editable_roles);
    //获取除了'subscriber'(订阅者)角色之外的所有角色的用户数据
    $subscriber_key = array_search('subscriber', $roles, true);
    if (false !== $subscriber_key) {
        $roles = array_slice($roles, 0, $subscriber_key);
    }
    $users = get_users(array('role__in' => $roles));
    //转为关联数组
    $user_data = array_map(function ($user) {
        return [
            'id'   => $user->ID,
            'name' => $user->display_name,
        ];
    }, $users);
    return $user_data;
}

//模块导入
function add_type_attribute_to_script_vue($tag, $handle)
{
    // 在这里判断需要添加 type 属性的 JS 文件，比如文件名包含 xxx.js
    if (strpos($tag, 'index.js') !== false) {
        // 在 script 标签中添加 type 属性
        $tag = str_replace('<script', '<script type="module"', $tag);
    }
    return $tag;
}
add_filter('script_loader_tag', 'add_type_attribute_to_script_vue', 10, 2);


//设置按钮
add_filter('plugin_action_links_' . plugin_basename(__FILE__), function ($links) {
    $links[] = '<a href="' . get_admin_url(null, '?page=vuespa_id') . '">' . __('设置', 'n') . '</a>';
    return $links;
});



//后台模块开发
